package AppleCakeMining;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import util.FileHandler;

public class GlobalAssociationRuleList {
	private static GlobalAssociationRuleList instance;
	private ArrayList<AssociationRule> rules;
	
	private GlobalAssociationRuleList() {
		rules = new ArrayList<AssociationRule>();
	}
	
	public static GlobalAssociationRuleList getInstance() {
		if (instance == null) {
			instance = new GlobalAssociationRuleList();
		}
		return instance;
	}

	public void addRule(AssociationRule ar) {
		rules.add(ar);
	}

	@SuppressWarnings("unchecked")
	public void printAllRules() {
		if(rules.size() == 0) return;
		Collections.sort(rules);
		Collections.reverse(rules);
		
		//write on file
		FileHandler fh = FileHandler.getInstance();
		String filename = "Rules-F"+Main.MINFREQPERCENT + "C"+ 	Main.MINCONFPERCENT  +".txt";
		String s = "Association rules\nMinimum frequency:" + Main.MINFREQPERCENT +
				" Minimum confidence:" + Main.MINCONFPERCENT +
				" " + rules.size() + " rules\n";
		fh.write(s, filename);
		for(AssociationRule ar:rules) {
			fh.write(ar+ "\n", filename);
		}
		fh.write("AssociationRules - Frequency:"+ Main.MINFREQPERCENT +
				" , Confidence:" + Main.MINCONFPERCENT + "  Items:" + rules.size()+ "\n", "metaresults.txt");
		//print on screen
		/*
		System.out.println(rules.size() + "rules");
		for(AssociationRule ar:rules) {
			System.out.println(ar);
		}*/		
	}

	public void clear() {
		rules = new ArrayList<AssociationRule>();
	}

	@SuppressWarnings("unchecked")
	public ArrayList<Item> generateBestExtension(Transaction t) {
		Collections.sort(rules);
		Collections.reverse(rules);
		ArrayList<Item> bestMatchingItems = new ArrayList<Item>();
		for(int i = 0; i < rules.size() && bestMatchingItems.size() < 500; ++i) {
			AssociationRule rule = rules.get(i);
			if(rule.isApplicable(t)) {
				ArrayList<Item> toAdd = getItemsNotInTransactionNorList(rule.getConsequent(), t.getItems(),bestMatchingItems);
				bestMatchingItems.addAll(toAdd);
			}
		}
		return bestMatchingItems;
	}

	private ArrayList<Item> getItemsNotInTransactionNorList(ArrayList<Item> candidates,	Collection<Item> items1, ArrayList<Item> items2) {
		ArrayList<Item> toAdd = new ArrayList<Item>();
		for(Item i:candidates) {
			if(!items1.contains(i) && !items2.contains(i)) {
				toAdd.add(i);
			}
		}
		return toAdd;
	}

}
